<?php
namespace Cyfy;
/**
 * The main class.
 *
 * This class contains configuration settings and has methods for operations with virtual filesystem as well as with real filesystem.
 *
 * @category cyfy
 * @author Dandelion <dandelion8888@gmail.com>
 * @version 0.1
 */ 
class Cyfy extends \Cyfy\Translatable
{
    
    /**
     * Query which is parsed from URL address.
     * @var string
     */
    static public $query = "";
    
    /**
     * Real query, that one which corresponds with DB. Usually same as $query.
     * @var string
     */
    static public $realQuery = "";
      
    /**
     * Where is cyfy saved relatively to www_root
     * @var string
     */
    static public $pathPrefix = "/";
    
    /**
     * Configuration directory
     * @var string
     */
    static public $configDir = "cfg/";
    
    /**
     * Files directory
     * @var string
     */
    static public $filesDir = "files/";
    
    /**
     * Modules directory
     * @var string
     */
    static public $modulesDir = "Cyfy/Modules/";
    
    /**
     * Templates directory
     * @var string
     */
    static public $templatesDir = "templates/";
    
    /**
     * Directory for temporary files
     * @var string
     */
    static public $tempDir = "tmp/";
    
    /**
     * Directory for log files
     * @var string
     */
    static public $logDir = "log/";
    
    /**
     * Debugging mode
     * @var bool
     */
    static public $debug = FALSE;
    
    /**
     * Template to be used
     * @var string
     */
    static public $template = "CoolBlue10";
    
    /**
     * Database server 
     * @var string
     */
    static public $dbHost = "localhost";
    
    /**
     * Database user
     * @var string
     */
    static public $dbUsername = "root";
    
    /**
     * Database password 
     * @var string
     */
    static public $dbPassword = "******";
    
    /**
     * Database name
     * @var string
     */
    static public $dbDatabase = "db";
    
    /**
     * Type of the database
     * @var string
     */
    static public $dbDriver = "mysql";
    
    /**
     * Prefix for tables in the DB
     * @var string
     */
    static public $dbPrefix = "";
    
    /**
     * Salt for passwords stored in database
     * @var string
     */
    static public $passwordSalt = "";

    /**
     * Arguments - splitted \Cyfy\Cyfy ::  $query
     */
    static private $args = null;
    
    /**
     * Returns one argument from QUERY
     * @param  int Position
     * @return string
     */
    static public function arg($pos)
    {
        // if not loaded
        if(self :: $args === null)
        {
            self :: $args = explode("/", self :: $query);
        }
        return self :: $args[$pos];
    }
      
    /**
     * Checks permissions
     *
     * Checks if current user has permissions to do the called operation.
     * Calls a method of a module User (simplification for programmers).
     *
     * @param string Module name
     * @param string Permission name
     * @return bool TRUE, if user has the permission, FALSE otherwise.
     */
    static public function permission($module, $permission)
    {
        return \Cyfy\Modules\Users\Current :: hasPermission($module, $permission);
    }
    
    /**
     * Triggers NO PERMISSION message.
     *
     * This method is called when user doesn't have a permission to an operation.
     *
     * @param bool Return message
     * @return mixed HTML code, when returning message. Or TRUE when not returning.
     */
    static public function noPermission($return = false)
    {
        if($return)
        {
            return \Cyfy\Message :: get(self :: t(30), \Cyfy\Message :: ERROR);
        }

        \Cyfy\Message :: set(self :: t(30), \Cyfy\Message :: ERROR);
        return true;
    }

    /**
     * Returns a formatted path for source files
     *
     * Returns a path which is used for inserting some images, JS or CSS files into web pages.
     * Example:
     * <code>
     *      \Cyfy\Cyfy ::  CSS(\Cyfy\Cyfy :: getSourcePath(\Cyfy\Cyfy ::  $modulesDir . "MyModuleName/somefile.css"));
     * </code>
     * @param string Path to be formated
     * @return string Formated path, which ends with forward slash.
     */
    static public function getSourcePath($url)
    {
        return self :: $pathPrefix . $url;
    }
    
    /**
     * Returns a formatted path for internal web page links
     *
     * Returns a path which is used for navigation between web pages generated by Cyfy.
     * It's because of using languages and nice URLs.
     * Example:
     * <code>
     *      <a href="<?php \Cyfy\Cyfy :: getPath("index") ?>;
     * </code>
     * @param string Path to be formated
     * @param string Language to get
     * @return string Formated path, which ends with forward slash.
     */
    static public function getPath($url, $language = '')
    {
        if(\Cyfy\Language :: $multilanguage)
        {
            if($language == '')
            {
                $language = \Cyfy\Language :: getActive();
            }
            return self :: getSourcePath($language . "/" . $url);
        }
        
        return self :: getSourcePath($url);
    }
    
    /**
     * Creates a directory. If fails, shows a message.
     *
     * @param string Directory name
     * @return bool TRUE if successful, FALSE otherwise.
     */
    static public function makeDirectory($dirname)
    {
        if(mkdir($dirname))
        {
            return true;
        }
        \Cyfy\Message :: set(self :: t(101, $dirname), \Cyfy\Message::ERROR);
        return false;
    }
    
    /**
     * Deletes a file, or directory.
     *
     * Deletes a file, or directory, recursively.
     * Uses a function <em>recursiveDelete()</em> from inc/functions.php
     *
     * @param string Path to be deleted
     * @param bool   Safe deletion, prevents from deleting unwanted files.
     * @return bool TRUE if successful, FALSE otherwise.
     */
    static public function delete($path, $safe = true)
    {
        // security, because of '/something' or '../something' 
        if($safe)
        {
            if(strpos($path, "../") !== false){
                return false;
            }
            // if found
            if(strpos($path, "/") !== false){
                // if first char
                if(strpos($path, "/") == 0){
                    return false;
                }
            }
        }
        // file exists - delete
        if(file_exists($path))
        {
            return recursiveDelete($path);
        }
    }
    
    /**
     * Handles JavaScript something.
     *
     * There are several variants to use this method:
     * <ul>
     * <li>Inserts a link to a JavaScript file to header</li>
     * <li>Inserts a link to a JavaScript file to footer</li>
     * <li>Inserts JavaScript content as a string to header</li>
     * <li>Returns a link to a JavaScript as a string</li>
     * <li>Returns JavaScript content as a string, which can be inserted inline</li>
     * </ul>
     *
     * @param string JavaScript content. Filename or JavaScript data.
     * @param string Can be 'inline', or 'file'.
     * @param string Can be empty '' when only returns, 'header' or 'footer'.
     * @return mixed If $type = inline returns HTML content, or TRUE if successful, FALSE otherwise.
     */
    static public function javaScript($content, $type = "inline", $place = "")
    {
        // Type
        switch($type) {
            case "inline":
                $out = "<script type=\"text/javascript\"> \n";
                $out .= "/* <![CDATA[ */ \n";
                $out .= $content . "\n";
                $out .= "/* ]]> */ \n";
                $out .= "</script> \n";
                break;
            case "file":
                $out = "<script type=\"text/javascript\" src=\"{$content}\"></script>";
                break;
            default:
                return false;      
        }
    
        // Place to be inserted
        switch($place)
        {
             case "":
                if ($type == "inline") {
                    return $out; 
                }
                if( $type == "file"){
                    \Cyfy\Template :: addHeader($out);
                }
                break;
            case "header":
                \Cyfy\Template :: addHeader($out);
                break;
                
            case "footer":
                \Cyfy\Template :: addFooter($out);
                break;
            
            default:
                return $out;
        }
        return true;
    }
    
    /**
     * Inserts a link to CSS file into the header.
     *
     * @param string Filename
     */
    static public function css($filename)
    {
        \Cyfy\Template :: addHeader("<link rel=\"stylesheet\" type=\"text/css\" href=\"{$filename}\" />");
    }
  
    /**
     * Checks, if the path is available to use
     *
     * Checks, if the path in the virtual filesysten is available to use
     * @param string Path
     * @param bool   If using native link - link as a regex
     * @return bool TRUE if path is NOT used, FALSE otherwise.
     */
    static function tryPath($path, $native = false)
    {
        if(!$native)
        {
            $path = strtr($path, array('/' => '\/'));
        }
        
        if(\dibi :: query("SELECT COUNT(fid) FROM [:cyfy:Cyfy-filesystem] WHERE [path] = %s", $path) -> fetchSingle() > 0)
        {
            return false;
        }
        return true;
    }
   
    /**
     * Registers the path
     *
     * Checks, if the path in the virtual filesysten is available to use.
     * If yes, registers it for a module
     *
     * @param string Path
     * @param string Module path will be registred for
     * @param string Unique identification for the module
     * @param string Title of the filesystem item
     * @param string Permission the user must have to access the page.
     * @param bool   If using native link - link as a regex
     * @return bool TRUE if registration successful, FALSE otherwise.
     */
    static function registerPath($path, $module, $id, $name = "", $permission = "", $native = false)
    {
        if (self :: tryPath($path))
        {
            if(!$native)
            {
                $path = strtr($path, array('/' => '\/'));
            }
        
            $values = array(
                'path' => $path,
                'module' => $module,
                'id' => $id,
                'name' => $name,
                'permission' => $permission
            );
            
            return \dibi :: query('INSERT INTO [:cyfy:Cyfy-filesystem]', $values);
        }
        return false;
    }
      
    /**
     * Unregisters the path
     *
     * @param bool   If using native link - link as a regex
     * @param string Path to be deleted
     */     
    static function unregisterPath($path, $native = false)
    {
        if(!$native)
        {
            $path = strtr($path, array('/' => '\/'));
        }
        return \dibi :: query("DELETE FROM [:cyfy:Cyfy-filesystem] WHERE path = %s", $path);
    }

    /**
     * Unregisters the path using module name (and id, if called)
     *
     * @param string Module name
     * @param string Custom ID
     * @return bool
     */     
    static function unregisterPathByModule($module, $id = '')
    {
        $query = array("DELETE FROM [:cyfy:Cyfy-filesystem] WHERE module = %s ", $module);
        
        if($id != '')
        {
            $query[] = ' AND [id] = %s';
            $query[] = $id;
        }
        
        return \dibi :: query($query);
    }
    
    /**
     * Redirects user to the URL
     *
     * Redirects user to the URL, uses cyfy :: getPath() for formatting the URL, when redirected locally
     *
     * @param string URL to be redirected to
     * @param bool TRUE if redirecting to another server
     */     
    static function redirectTo($url, $outside = false)
    {
        if(!$outside)
        {
            $url = self :: getPath($url);
        }
        
        // redirecting
        @header("Location: ".$url);
        // if the redirecting doesn't work - print a link
        print("<a href=\"{$url}\">Click to be redirected.</a>");
        include("_end.php");
    }
}
